home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
- * ISO MPEG Audio Subgroup Software Simulation Group (1996)
- * ISO 13818-3 MPEG-2 Audio Encoder - Lower Sampling Frequency Extension
- *
- * $Id: musicin.c,v 1.2 1997/01/19 22:28:29 rowlands Exp $
- *
- * $Log: musicin.c,v $
- * Revision 1.2 1997/01/19 22:28:29 rowlands
- * Layer 3 bug fixes from Seymour Shlien
- *
- * Revision 1.1 1996/02/14 04:04:23 rowlands
- * Initial revision
- *
- * Received from Mike Coleman
- **********************************************************************/
- #include <fcntl.h>
-
- #include <stdlib.h>
- #include "common.h"
- #include "globalflags.h"
- #include "encoder.h"
- #include "l3psy.h"
- #include "mdct.h"
- #include "loop.h"
- #include "l3bitstream.h"
- #include "gtkanal.h"
- #include "version.h"
- #include <assert.h>
- #ifdef __FreeBSD__
- #include <floatingpoint.h>
- #endif
- #ifdef linux
- #include <fpu_control.h>
- #endif
-
-
- #include <time.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- /* Global flags. set defaults here, defined extern in common.h */
- int autoconvert=FALSE;
- int force_ms=FALSE;
- int gpsycho=1;
- int sfb21=1;
- int VBR=0;
- int VBR_q=4;
- #ifdef _BLADEDLL
- int silent=1;
- #else
- int silent=0;
- #endif
- int highq=0;
- int fast_mode=0;
- int allow_diff_short=0;
- #ifdef DISTRIB
- int gtkflag=1;
- #else
- int gtkflag=0;
- #endif
-
- void usage();
-
- /* Global variable definitions for "musicin.c" */
- struct stat sb;
- int firstcall = 1; /* define like this so Dll/BladeMP3EncDll.c can change value */
- int target_bitrate;
- long totalframes;
- int swapbytes = FALSE; /* force byte swapping */
- FILE *musicin;
- Bit_stream_struc bs;
- char *programName;
- int iswav=0;
-
- short FAR BigBuf[2][2304];
-
- FLOAT snr32[32];
- L3SBS FAR l3_sb_sample;
-
- III_side_info_t l3_side;
- frame_params fr_ps;
- unsigned long num_samples;
- int frameNum=0;
- #ifdef HAVEGTK
- static int MPGLAG=1;
- #endif
- int original_file_type; /* 0=WAV, 1=MP3 */
- int original_file_fd; /* file descriptor */
-
- /* Implementations */
-
- /*********************************************************/
- /* Timeconvert: convert given time (in secs) to hh:mm:ss */
- /*********************************************************/
- void timestatus(int frameNum, int totalframes, int samp_rate)
- {
- int time_so_far;
- int remain,estimated;
- double speedup;
- char str1[20],str2[20],str3[20];
-
- time_so_far = clock()/CLOCKS_PER_SEC;
- /* calc estimated total CPU time */
- estimated = (int)((float)totalframes/(float)frameNum * (float)time_so_far);
- remain=estimated - time_so_far;
-
- /* estimated encoding time / playing time. (protected from divide by 0) */
- speedup = (estimated*totalframes*1.152)/
- (1e-12+samp_rate*estimated*estimated);
-
- sprintf(str1,"%02d:%02d",(time_so_far/60)%60, time_so_far%60);
- sprintf(str2,"%02d:%02d",(remain/60)%60, remain%60);
- sprintf(str3,"%02d:%02d",(estimated/60)%60, estimated%60);
-
- fprintf(stderr,
- /*"Frame: [%4lu/%4lu] Encoding Time %5s/%5s (%.2fx) ETA %5s\r", */
- "Frame: [%4d/%4d] Encoding Time %5s/%5s (%.2fx) ETA %5s\r",
- frameNum,totalframes,str1,str3,speedup,str2);
- fflush(stderr);
- }
-
-
-
-
- /************************************************************************
- *
- * parse_args
- *
- * PURPOSE: Sets encoding parameters to the specifications of the
- * command line. Default settings are used for parameters
- * not specified in the command line.
- *
- * If the input file is in AIFF format, the sampling frequency is read
- * from the AIFF header.
- *
- * The input and output filenames are read into #inpath# and #outpath#.
- *
- ************************************************************************/
-
- void
- parse_args(argc, argv, fr_ps, psy, num_samples, inPath, outPath)
- int argc;
- char **argv;
- frame_params *fr_ps;
- int *psy;
- unsigned long *num_samples;
- char inPath[MAX_NAME_SIZE];
- char outPath[MAX_NAME_SIZE];
- {
- FLOAT srate;
- int brate;
- layer *info = fr_ps->header;
- int err = 0, i = 0;
- IFF_AIFF pcm_aiff_data;
- long samplerate;
- long soundPosition;
- char ckwav[5]={0,0,0,0,0};
-
- /* preset defaults */
- inPath[0] = '\0'; outPath[0] = '\0';
- info->lay = DFLT_LAY;
- switch(DFLT_MOD) {
- case 's': info->mode = MPG_MD_STEREO; info->mode_ext = 0; break;
- case 'd': info->mode = MPG_MD_DUAL_CHANNEL; info->mode_ext=0; break;
- case 'j': info->mode = MPG_MD_JOINT_STEREO; info->mode_ext=0; break;
- case 'm': info->mode = MPG_MD_MONO; info->mode_ext = 0; break;
- default:
- fprintf(stderr, "%s: Bad mode dflt %c\n", programName, DFLT_MOD);
- abort();
- }
- *psy = DFLT_PSY;
- if((info->sampling_frequency = SmpFrqIndex((long)(1000*DFLT_SFQ), &info->version)) < 0) {
- fprintf(stderr, "%s: bad sfrq default %.2f\n", programName, DFLT_SFQ);
- abort();
- }
- info->bitrate_index = 9;
- brate = 0;
- switch(DFLT_EMP) {
- case 'n': info->emphasis = 0; break;
- case '5': info->emphasis = 1; break;
- case 'c': info->emphasis = 3; break;
- default:
- fprintf(stderr, "%s: Bad emph dflt %c\n", programName, DFLT_EMP);
- abort();
- }
- info->copyright = 0;
- info->original = 1;
- info->error_protection = FALSE;
-
- /* process args */
- while(++i<argc && err == 0) {
- char c, *token, *arg, *nextArg;
- int argUsed;
-
- token = argv[i];
- if(*token++ == '-') {
- if(i+1 < argc) nextArg = argv[i+1];
- else nextArg = "";
- argUsed = 0;
- if (! *token) {
- /* The user wants to use stdin and/or stdout. */
- if(inPath[0] == '\0') strcpy(inPath, argv[i]);
- else if(outPath[0] == '\0') strcpy(outPath, argv[i]);
- }
- while( (c = *token++) ) {
- if(*token ) arg = token;
- else arg = nextArg;
- switch(c) {
- case 'm': argUsed = 1;
- if (*arg == 's')
- { info->mode = MPG_MD_STEREO; info->mode_ext = 0; }
- else if (*arg == 'd')
- { info->mode = MPG_MD_DUAL_CHANNEL; info->mode_ext=0; }
- else if (*arg == 'j')
- { info->mode = MPG_MD_JOINT_STEREO; info->mode_ext=0; }
- else if (*arg == 'f')
- { info->mode = MPG_MD_JOINT_STEREO; force_ms=1; info->mode_ext=0; }
- else if (*arg == 'm')
- { info->mode = MPG_MD_MONO; info->mode_ext = 0; }
- else {
- fprintf(stderr,"%s: -m mode must be s/d/j/f/m not %s\n",
- programName, arg);
- err = 1;
- }
- break;
- case 'V': argUsed = 1; VBR = 1;
- if (*arg == '0')
- { VBR_q=0; }
- else if (*arg == '1')
- { VBR_q=1; }
- else if (*arg == '2')
- { VBR_q=2; }
- else if (*arg == '3')
- { VBR_q=3; }
- else if (*arg == '4')
- { VBR_q=4; }
- else if (*arg == '5')
- { VBR_q=5; }
- else if (*arg == '6')
- { VBR_q=6; }
- else if (*arg == '7')
- { VBR_q=7; }
- else if (*arg == '8')
- { VBR_q=8; }
- else if (*arg == '9')
- { VBR_q=9; }
- else {
- fprintf(stderr,"%s: -V n must be 0-9 not %s\n",
- programName, arg);
- err = 1;
- }
- break;
-
- case 's':
- argUsed = 1;
- srate = atof( arg );
- /* samplerate = rint( 1000.0 * srate ); $A */
- samplerate = (long) (( 1000.0 * srate ) + 0.5);
- if( (info->sampling_frequency =
- SmpFrqIndex((long) samplerate, &info->version)) < 0 )
- err = 1;
- break;
-
- case 'b':
- argUsed = 1;
- brate = atoi(arg);
- break;
- case 'x': /* force byte swapping */
- swapbytes=TRUE;
- break;
- case 'a': /* autoconvert input file from stereo to mono - for mono mp3 encoding */
- autoconvert = TRUE;
- break;
- case 'h':
- highq = TRUE;
- break;
- case 'k':
- sfb21 = FALSE;
- break;
- case 'd':
- allow_diff_short = 1;
- break;
- case 'v':
- VBR = 1;
- gpsycho=1;
- break;
- case 'S':
- silent = TRUE;
- break;
- case 'f':
- fast_mode = TRUE;
- break;
- case 'O':
- gpsycho = FALSE;
- break;
- #ifdef HAVEGTK
- case 'g': /* turn on gtk analysis */
- gtkflag = TRUE;
- #endif
- break;
- case 'e': argUsed = 1;
- if (*arg == 'n') info->emphasis = 0;
- else if (*arg == '5') info->emphasis = 1;
- else if (*arg == 'c') info->emphasis = 3;
- else {
- fprintf(stderr,"%s: -e emp must be n/5/c not %s\n",
- programName, arg);
- err = 1;
- }
- break;
- case 'c': info->copyright = 1; break;
- case 'o': info->original = 0; break;
- default: fprintf(stderr,"%s: unrec option %c\n",
- programName, c);
- err = 1; break;
- }
- if(argUsed) {
- if(arg == token) token = ""; /* no more from token */
- else ++i; /* skip arg we used */
- arg = ""; argUsed = 0;
- }
- }
- }
- else {
- if(inPath[0] == '\0') strcpy(inPath, argv[i]);
- else if(outPath[0] == '\0') strcpy(outPath, argv[i]);
- else {
- fprintf(stderr,"%s: excess arg %s\n", programName, argv[i]);
- err = 1;
- }
- }
- }
-
- if(err || inPath[0] == '\0') usage(); /* never returns */
-
- if (inPath[0]=='-') silent=1; /* turn off status - it's broken for stdin */
-
-
- if(outPath[0] == '\0') {
- if (inPath[0]=='-') {
- /* if input is stdin, default output is stdout */
- strcpy(outPath,"-");
- }else {
- strcpy(outPath, inPath);
- strcat(outPath, DFLT_EXT);
- }
-
- }
-
- // SPECIAL FOR BLADE ENCODER
- #ifdef _BLADEDLL
- open_bit_stream_w(&bs, outPath, BUFFER_SIZE);
- #else
- original_file_type=!(strcmp((char *) &inPath[strlen(inPath)-4],".mp3"));
-
- if (original_file_type) {
- /* MP3 file. */
- totalframes = -1;
- original_file_fd = open(inPath,O_RDONLY);
- if (original_file_fd == -1) {
- fprintf(stderr,"Could not find \"%s\".\n", inPath);
- exit(1);
- }
- if (!gtkflag) {
- fprintf(stderr,"Use option -g to analyze mp3 files.\n");
- exit(1);
- }
-
- }
- else {
- if (!strcmp(inPath, "-")) {
- /* Read from standard input. */
- musicin = stdin;
- } else {
- if ((musicin = fopen(inPath, "rb")) == NULL) {
- fprintf(stderr, "Could not find \"%s\".\n", inPath);
- exit(1);
- }
- }
- #ifdef DISTRIB
- outPath="/dev/null";
- #endif
- open_bit_stream_w(&bs, outPath, BUFFER_SIZE);
- if ((soundPosition = aiff_read_headers(musicin, &pcm_aiff_data)) != -1) {
-
- fprintf(stderr, "Found Audio IFF sound file headers: ");
-
- aiff_check(inPath, &pcm_aiff_data, &info->version);
-
- if (fseek(musicin, soundPosition, SEEK_SET) != 0) {
- /*
- fprintf(stderr, "Could not seek to PCM sound data in \"%s\".\n", inPath);
- exit(1);
- */
- fprintf(stderr,"Could not seek to PCM sound data in \"%s\".\n",inPath);
- fprintf(stderr,"Crossing Fingers.....\n");
-
- }
-
- info->sampling_frequency = SmpFrqIndex((long)pcm_aiff_data.sampleRate, &info->version);
- fprintf(stderr, "%.1f kHz samples\n",
- pcm_aiff_data.sampleRate/1000);
-
- /* Determine number of samples in sound file */
-
- *num_samples = (long)(pcm_aiff_data.numChannels) *
- (long)(pcm_aiff_data.numSampleFrames);
-
- if ( pcm_aiff_data.numChannels == 1 ) {
- info->mode = MPG_MD_MONO;
- info->mode_ext = 0;
- }
- }
- else { /* Not using Audio IFF sound file headers. */
-
- if (fseek(musicin, 8, SEEK_SET) != 0) {
- /*
- fprintf(stderr, "Could not seek to PCM sound data in \"%s\".\n", inPath);
- exit(1);
- */
- fprintf(stderr,"Could not seek to PCM sound data in \"%s\".\n",inPath);
- fprintf(stderr,"Crossing Fingers.....\n");
- }
-
- fread(ckwav, 4, 1, musicin);
- if (strncmp(ckwav, "WAVE",4)==0) {
- iswav = 1;
- fseek(musicin, 0x2c, SEEK_SET); /* skip wav file header */
- /* NO PARSING OF WAV HEADERS YET */
- fprintf(stderr, "%s : Found WAV header. Assuming 44.1khz 16bit stereo samples\n",ckwav);
- }
- else {
- fseek(musicin, 0, SEEK_SET);
- fprintf(stderr, "Assuming raw pcm input file");
- if (swapbytes==TRUE)
- fprintf(stderr, " : Forcing byte-swapping\n");
- else
- fprintf(stderr, "\n");
- }
-
- /* Declare sound file to have "infinite" number of samples. */
- *num_samples = MAX_U_32_NUM;
- }
- /* Timing, autoconvert and resampling checks and setup */
- stat(inPath,&sb);
- totalframes = sb.st_size/4608;
- if ((info->mode == MPG_MD_MONO)&&(autoconvert==FALSE))
- totalframes *= 2;
- if (autoconvert==TRUE) {
- fprintf(stderr, "Autoconverting from stereo to mono. Setting encoding to mono mode.\n");
- info->mode = MPG_MD_MONO;
- info->mode_ext = 0;
- }
- }
- #endif // END OF BLADE ENCODER SPECIAL
-
- if ( brate == 0 ) {
- if (VBR) brate = bitrate[info->version][info->lay-1][8];
- else brate = bitrate[info->version][info->lay-1][9];
- }
- if( (info->bitrate_index = BitrateIndex(info->lay, brate, info->version)) < 0)
- err=1;
- if(err || inPath[0] == '\0') usage(); /* never returns */
- target_bitrate = info->bitrate_index;
- if (info->bitrate_index==14) VBR=0; /* dont bother with VBR at 320kbs */
- }
-
- /************************************************************************
- *
- * print_config
- *
- * PURPOSE: Prints the encoding parameters used
- *
- ************************************************************************/
-
- void print_config( frame_params *fr_ps, int *psy, char *inPath, char *outPath)
- {
- layer *info = fr_ps->header;
- #if 0
- fprintf(stderr, "Encoding configuration:\n");
- fprintf(stderr, "Algorithm=%s\n", version_names[info->version]);
- if(info->mode != MPG_MD_JOINT_STEREO)
- fprintf(stderr, "Layer=III mode=%s extn=%d psy model=%d\n",
- mode_names[info->mode], info->mode_ext, *psy);
- else fprintf(stderr, "Layer=III mode=%s extn=data dependant psy model=%d\n",
- mode_names[info->mode], *psy);
- fprintf(stderr, "samp frq=%.1f kHz total bitrate=%d kbps\n",
- s_freq[info->version][info->sampling_frequency],
- bitrate[info->version][info->lay-1][info->bitrate_index]);
- fprintf(stderr, "de-emph=%d c/right=%d orig=%d\n",
- info->emphasis, info->copyright, info->original);
- fprintf(stderr, "input file: '%s' output file: '%s'\n", inPath, outPath);
- #endif
- if (original_file_type) {
- fprintf(stderr, "Analyzing %s \n",inPath);
- }
- else {
- fprintf(stderr, "Encoding %s to %s\n",
- (strcmp(inPath, "-")? inPath : "stdin"),
- (strcmp(outPath, "-")? outPath : "stdout"));
- if (VBR)
- fprintf(stderr, "Encoding as %.1f kHz VBR(min: %d kbps) %s MPEG-1 LayerIII file\n",
- s_freq[info->version][info->sampling_frequency],
- bitrate[info->version][info->lay-1][info->bitrate_index],
- mode_names[info->mode]);
- else
- fprintf(stderr, "Encoding as %.1f kHz %d kbps %s MPEG-1 LayerIII file\n",
- s_freq[info->version][info->sampling_frequency],
- bitrate[info->version][info->lay-1][info->bitrate_index],
- mode_names[info->mode]);
- }
- }
-
-
- #ifdef HAVEGTK
- int readframe()
- {
- int j,ch,stereo,out=0;
- short mpg123pcm[2][1152];
- static int frameNum=0;
-
- stereo = fr_ps.stereo;
- frameNum++;
-
- /* create a 1 frame lag so MP3 analysis syncs with WAV analysis */
- if (frameNum == 1 ) out=1152;
- else out=decode1file(original_file_fd,mpg123pcm,stereo);
-
-
- /* delay pcm data by yet another frame */
- for ( ch = 0; ch < stereo; ch++ ) {
- for ( j = 0; j < DECDELAY; j++ )
- pinfo->pcmdata2[ch][j] = pinfo->pcmdata2[ch][j+1152];
- for ( j = 0; j < 1152; j++ ) {
- pinfo->pcmdata2[ch][j+DECDELAY] = mpg123pcm[ch][j];
- }
- }
- MPGLAG = 2;
- pinfo->frameNum = frameNum;
- pinfo->mpglag = MPGLAG;
- return out;
- }
- #endif
-
-
-
-
- int makeframe()
- {
- static unsigned long frameBits, sentBits = 0;
- static unsigned long bitsPerSlot;
- static double frac_SpF;
- static double slot_lag;
- static int mode_gr;
- static int mpg123count=0;
-
- int j,ch,gr,mean_bits;
- double xr[2][2][576];
- double xr_dec[2][2][576];
- double pe[2][2];
- double pe3[2];
- int l3_enc[2][2][576];
- III_psy_ratio ratio,ratio3;
- III_scalefac_t scalefac;
- int blocktype[2];
- int blocktype3[2];
- int bitsPerFrame;
- short *win_buf[2];
- double win_que[2][HAN_SIZE];
- int stereo;
- int iread;
- layer *info;
- int i;
-
- #ifdef HAVEGTK
- char mpg123bs[BUFFER_SIZE];
- short mpg123pcm[2][1152];
- #endif
- int check_ms_stereo;
- int bit_rate;
- double samp;
- double ms_ener_ratio[2];
-
-
- stereo = fr_ps.stereo;
- info = fr_ps.header;
- #ifdef HAVEGTK
- if (gtkflag) {
- pinfo->frameNum = frameNum;
- pinfo->sampfreq=s_freq[info->version][info->sampling_frequency]*1000.0;
- }
- #endif
-
- info->mode_ext = 0;
-
- /* use m/s stereo? */
- check_ms_stereo = ((info->mode == MPG_MD_JOINT_STEREO) &&
- (!force_ms) &&
- (stereo==2) &&
- (gpsycho));
-
- info->bitrate_index = target_bitrate;
- bit_rate = bitrate[info->version][info->lay-1][info->bitrate_index];
- samp = s_freq[info->version][info->sampling_frequency];
-
- if (firstcall) {
- double avg_slots_per_frame;
- unsigned long samplesPerFrame;
- int whole_SpF;
- firstcall = 0;
- mpg123count=0;
-
-
- /* Figure average number of 'slots' per frame. */
- /* Bitrate means TOTAL for both channels, not per side. */
- bitsPerSlot = 8;
- samplesPerFrame = info->version == 1 ? 1152 : 576;
- avg_slots_per_frame = ((double)samplesPerFrame /samp) *
- ((double)bit_rate / (double)bitsPerSlot);
- whole_SpF = (int) avg_slots_per_frame;
- frac_SpF = avg_slots_per_frame - (double)whole_SpF;
- slot_lag = -frac_SpF;
- info->padding = 1;
- if (fabs(frac_SpF) < 1e-9) info->padding = 0;
- mode_gr = (info->version == 1) ? 2 : 1; /* mode_gr = 2 */
- if (mode_gr != 2) exit(-99);
-
- #ifndef _BLADEDLL
- // AF, modified this code, so it will read to first samples into the lower halve of
- // the buffer, this way it is easier to support the _BLADEDLL hack
- iread = get_audio(musicin,&BigBuf[0][0],&BigBuf[1][0],num_samples,fr_ps.stereo,fr_ps.header);
- #else
- // Don't read the data, it is already in the BugBuf
- {
- extern int nBladeBufferSize;
- iread=nBladeBufferSize;
- }
- #endif
-
- /* we are still working with short int, so we cannot devide by
- * sqrt(2) (overflow). divide by 2, rescale later */
- if (force_ms)
- {
- // AF: Correct the lower halve of the buffer, instead of the upper halve
- for (i=0; i< 1152; i++)
- {
- double mid = (BigBuf[0][i]+BigBuf[1][i])/(2.0);
- double side= (BigBuf[0][i]-BigBuf[1][i])/(2.0);
- BigBuf[0][i]=mid;
- BigBuf[1][i]=side;
-
- }
- }
- }
- #ifndef _BLADEDLL
- else
- {
- // AF: If not the first call, do shift the data
- // Shift the data from the upper halve of the BigBuf to to lower halve
- for (ch=0; ch<2; ch++)
- for (i=0; i<1152; i++)
- BigBuf[ch][i]=BigBuf[ch][i+1152];
- }
- // Read the sam
- iread = get_audio(musicin,&BigBuf[0][1152],&BigBuf[1][1152],num_samples,fr_ps.stereo,fr_ps.header);
- #else
- {
- // Don't read the data, it is already in the BugBuf
- extern int nBladeBufferSize;
- iread=nBladeBufferSize;
- }
- #endif
-
-
-
- /********************** padding *****************************/
- if (VBR) {
- /* leave info_padding as it was set above */
- } else {
- if (frac_SpF != 0) {
- if (slot_lag > (frac_SpF-1.0) ) {
- slot_lag -= frac_SpF;
- info->padding = 0;
- }
- else {
- info->padding = 1;
- slot_lag += (1-frac_SpF);
- }
- }
- }
-
-
-
-
-
- /********************** process InputBuffer *****************************/
- frameNum++;
-
- if (force_ms)
- for (i=0; i< 1152; i++) {
- double mid = (BigBuf[0][1152+i]+BigBuf[1][1152+i])/(2.0);
- double side= (BigBuf[0][1152+i]-BigBuf[1][1152+i])/(2.0);
- BigBuf[0][1152+i]=mid;
- BigBuf[1][1152+i]=side;
- }
-
- if (frameNum%10==0 && !gtkflag && !silent) {
- timestatus(frameNum,totalframes,s_freq[info->version][info->sampling_frequency]);
- }
-
-
- /***************************** Layer 3 **********************************/
- win_buf[0] = &BigBuf[0][0];
- win_buf[1] = &BigBuf[1][0];
-
-
- if (!fast_mode) {
- /* psychoacoustic model */
- /* this mess will be cleaned up in the future. It is coded like this
- * to maintain original ISO and GPSYCHO psy-models
- */
- short int *bufp[2]; /* address of beginninf of left & right granule */
- gr = 0;
- if (frameNum ==1 ) {
- /* prime the psy-model pump */
- for ( ch = 0; ch < stereo; ch++ )
- bufp[ch]=&BigBuf[ch][gr*576];
- L3psycho_anal( bufp,stereo,gr, info,
- s_freq[info->version][info->sampling_frequency] * 1000.0,
- check_ms_stereo,&ms_ener_ratio[0],
- ratio.l[gr], ratio.s[gr],
- pe[gr], blocktype);
- if (!gpsycho) {
- for ( ch = 0; ch < stereo; ch++ )
- l3_side.gr[gr].ch[ch].tt.block_type=blocktype[ch];
- }
- } else {
- if (!gpsycho){
- memcpy(&ratio,&ratio3,sizeof(ratio));
- for ( ch = 0; ch < stereo; ch++ ) {
- pe[gr][ch]=pe3[ch];
- l3_side.gr[0].ch[ch].tt.block_type=blocktype3[ch];
- }
- }
- }
-
- gr = 1;
- for ( ch = 0; ch < stereo; ch++ )
- bufp[ch]=&BigBuf[ch][gr*576];
- L3psycho_anal( bufp, stereo,gr, info,
- s_freq[info->version][info->sampling_frequency] * 1000.0,
- check_ms_stereo,&ms_ener_ratio[0],
- ratio.l[gr], ratio.s[gr],
- pe[gr], blocktype);
- for ( ch = 0; ch < stereo; ch++ ) {
- if (gpsycho) {
- /* data returned for gr=0: memcpy */
- pe[0][ch]=pe[1][ch];
- memcpy(&ratio.l[0][ch][0],&ratio.l[1][ch][0],sizeof(ratio.l[gr][ch]));
- memcpy(&ratio.s[0][ch][0],&ratio.s[1][ch][0],sizeof(ratio.s[gr][ch]));
- l3_side.gr[0].ch[ch].tt.block_type=blocktype[ch];
- } else {
- l3_side.gr[gr].ch[ch].tt.block_type=blocktype[ch];
- }
- }
- /* do a third call */
- gr = 0;
- for ( ch = 0; ch < stereo; ch++ )
- bufp[ch]=&BigBuf[ch][1152 + gr*576];
- L3psycho_anal( bufp, stereo,gr, info,
- s_freq[info->version][info->sampling_frequency] * 1000.0,
- check_ms_stereo,&ms_ener_ratio[1],
- ratio3.l[gr], ratio3.s[gr],
- pe3, blocktype3);
- for ( ch = 0; ch < stereo; ch++ ) {
- if (gpsycho) {
- /* data returned for gr=1, prev. frame. memcpy */
- pe[1][ch]=pe3[ch];
- memcpy(&ratio.l[1][ch][0],&ratio3.l[0][ch][0],sizeof(ratio3.l[0][ch]));
- memcpy(&ratio.s[1][ch][0],&ratio3.s[0][ch][0],sizeof(ratio3.s[0][ch]));
- l3_side.gr[1].ch[ch].tt.block_type=blocktype3[ch];
- }
- }
- }
-
- /* block type flags */
- for( gr = 0; gr < mode_gr; gr++ ) {
- for ( ch = 0; ch < stereo; ch++ ) {
- gr_info *cod_info = &l3_side.gr[gr].ch[ch].tt;
- cod_info->mixed_block_flag = 0; /* never used by this model */
- if (cod_info->block_type == NORM_TYPE )
- cod_info->window_switching_flag = 0;
- else
- cod_info->window_switching_flag = 1;
- }
- }
-
-
- /* polyphase filtering */
- for( gr = 0; gr < mode_gr; gr++ )
- for ( ch = 0; ch < stereo; ch++ )
- for ( j = 0; j < 18; j++ ) {
- window_subband( &win_buf[ch], &win_que[ch][0], ch );
- filter_subband( &win_que[ch][0], &(l3_sb_sample)[ch][gr+1][j][0] ); }
-
- /* apply mdct to the polyphase outputs */
- mdct_sub( &l3_sb_sample, xr, stereo, &l3_side, mode_gr );
-
-
- /* data was scaled by 1/2. fix so effectively it was scaled by 1/sqrt(2) */
- if (force_ms) {
- for ( gr = 0; gr < mode_gr; gr++ )
- for ( ch = 0; ch < stereo; ch++ )
- for (i =0 ; i< 576; i++)
- xr[gr][ch][i] *= sqrt(2.0);
- }
-
-
- if (check_ms_stereo) {
- /* make sure block type is the same in each channel */
- check_ms_stereo =
- (l3_side.gr[0].ch[0].tt.block_type==l3_side.gr[0].ch[1].tt.block_type) &&
- (l3_side.gr[1].ch[0].tt.block_type==l3_side.gr[1].ch[1].tt.block_type);
- }
-
- if (check_ms_stereo) {
- if ((ms_ener_ratio[0]+ms_ener_ratio[1])<.7 ) info->mode_ext = 2;
- }
-
- #ifdef HAVEGTK
- if (gtkflag) {
- for ( gr = 0; gr < mode_gr; gr++ )
- for ( ch = 0; ch < stereo; ch++ ) {
- pinfo->ms_ratio[gr]=ms_ener_ratio[gr];
- pinfo->blocktype[gr][ch]=
- l3_side.gr[gr].ch[ch].tt.block_type;
- for ( j = 0; j < 576; j++ ) pinfo->xr[gr][ch][j]=xr[gr][ch][j];
- }
- }
- #endif
-
-
- /* bit and noise allocation */
- iteration_loop( pe, ms_ener_ratio, xr, &ratio, &l3_side, l3_enc,
- xr_dec, &scalefac, &fr_ps);
-
-
- /* flag for our ms_stereo with psy-model on mid & side channels */
- if (force_ms) info->mode_ext = 2;
-
-
- /* write the frame to the bitstream */
- getframebits(info,stereo,&bitsPerFrame,&mean_bits);
- III_format_bitstream( bitsPerFrame, &fr_ps, l3_enc, &l3_side,
- &scalefac, &bs, xr, NULL, 0 );
-
-
- frameBits = sstell( &bs ) - sentBits;
-
-
- if ( frameBits % bitsPerSlot ) /* a program failure */
- fprintf( stderr, "Sent %ld bits = %ld slots plus %ld\n",
- frameBits, frameBits/bitsPerSlot,
- frameBits%bitsPerSlot );
- sentBits += frameBits;
-
-
- #ifdef HAVEGTK
- /* copy bit buffer into array and send to mpg123 to synthesis the pcm data */
- if (gtkflag) {
- mpg123count=0;
- for (i=bs.buf_size-1 ; i > bs.buf_byte_idx ; (i-- ))
- mpg123bs[mpg123count++]=bs.buf[i];
- /* re-synthesize pcm data from mp3 frame */
- if (!decode1(mpg123bs,mpg123count,&mpg123pcm,stereo)) {
- if (MPGLAG == MAXMPGLAG)
- fprintf(stderr, "MAXMPGLAG set too low. The following frames will be mis-aligned \n");
- else MPGLAG+=1;
- }
- pinfo->mpglag = MPGLAG;
- }
-
- /* empty data from bit buffer into mp3 file */
- empty_buffer(&bs, 1+bs.buf_byte_idx);
- bs.buf[bs.buf_byte_idx] = 0;
-
- if (gtkflag) {
- for ( ch = 0; ch < stereo; ch++ ) {
- for ( j = 0; j < WINDELAY; j++ )
- pinfo->pcmdata[ch][j] = pinfo->pcmdata[ch][j+1152];
- for ( j = 0; j < 1152; j++ ) {
- pinfo->pcmdata[ch][j+WINDELAY] = BigBuf[ch][j];
- }
- }
- for ( ch = 0; ch < stereo; ch++ ) {
- for ( j = 0; j < DECDELAY; j++ )
- pinfo->pcmdata2[ch][j] = pinfo->pcmdata2[ch][j+1152];
- for ( j = 0; j < 1152; j++ ) {
- pinfo->pcmdata2[ch][j+DECDELAY] = mpg123pcm[ch][j];
- }
- }
- pinfo->frameNum = frameNum;
- }
- #endif
- return iread/stereo;
- }
-
- /************************************************************************
- *
- * main
- *
- * PURPOSE: MPEG-1 Layer III encoder, with
- * psychoacoustic models ISO-2 (AT&T) and GPSYCHO
- *
- * SEMANTICS: One overlapping frame of audio of up to 2 channels are
- * processed at a time in the following order:
- * (associated routines are in parentheses)
- *
- * 1. Filter sliding window of data to get 32 subband
- * samples per channel.
- * (window_subband,filter_subband)
- *
- * 2. Calculate scalefactors for the frame, and if layer 2,
- * also calculate scalefactor select information.
- * (*_scale_factor_calc)
- *
- * 3. Calculate psychoacoustic masking levels using selected
- * psychoacoustic model.
- * (*_Psycho_One, psycho_anal)
- *
- * 4. Perform iterative bit allocation for subbands with low
- * mask_to_noise ratios using masking levels from step 4.
- * (*_main_bit_allocation)
- *
- * 5. Pack bit allocation and scalefactors onto bitstream.
- * (*_encode_bit_alloc,*_encode_scale)
- *
- * 6. Quantize subbands and pack them into bitstream
- * (*_subband_quantization, *_sample_encoding)
- *
- ************************************************************************/
-
-
-
- int main(argc, argv)
- int argc;
- char **argv;
- {
-
- char original_file_name[MAX_NAME_SIZE];
- char encoded_file_name[MAX_NAME_SIZE];
- int model, stereo;
- layer info;
- char lpszVersion[80];
-
- #ifdef HAVEGTK
- gtk_init (&argc, &argv);
- #endif
- #ifdef __FreeBSD__
- {
- fp_except_t mask;
- mask=fpgetmask();
- /* printf("FreeBSD mask is 0x%x\n",mask); */
- }
- #endif
- #ifdef linux
- {
- unsigned int mask;
- _FPU_GETCW(mask);
- /* Set the Linux mask to the FreeBSD default mask */
- mask &= ~( _FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM );
- _FPU_SETCW(mask);
- }
- #endif
-
- /* clear buffers */
- memset((char *) BigBuf, 0, sizeof(BigBuf));
- memset((char *) snr32, 0, sizeof(snr32));
-
- // Clear info structure
- memset(&info,0,sizeof(info));
-
- fr_ps.header = &info;
- fr_ps.tab_num = -1; /* no table loaded */
- fr_ps.alloc = NULL;
- info.version = MPEG_AUDIO_ID; /* =1 Default: MPEG-1 */
- info.extension = 0;
-
- /* get version string */
- if (gpsycho && !original_file_type)
- fprintf(stderr,"LAME version %s (www.sulaco.org/mp3) \n",get_lame_version(lpszVersion));
-
-
- programName = argv[0];
- if(argc==1) /* no command-line args
- obtain_parameters(&fr_ps, &model, &num_samples,
- original_file_name, encoded_file_name);*/
- usage();
- else
- parse_args(argc, argv, &fr_ps, &model, &num_samples,
- original_file_name, encoded_file_name);
- print_config(&fr_ps, &model,
- original_file_name, encoded_file_name);
-
- hdr_to_frps(&fr_ps);
- stereo = fr_ps.stereo;
- if (gpsycho && !original_file_type) fprintf(stderr,
- "using GPSYCHO: GPL'd psycho-acoustic model \n");
-
- #ifdef HAVEGTK
- if (gtkflag) gtkcontrol(totalframes,original_file_type,original_file_name,gpsycho);
- else
- #endif
- while (makeframe());
-
- /* clean up if we were analyzing a wav file */
- if (!original_file_type) {
- if ( info.lay == 3 ) III_FlushBitstream();
- close_bit_stream_w( &bs );
-
- if (fclose(musicin) != 0){
- fprintf(stderr, "Could not close \"%s\".\n", original_file_name);
- exit(2);
- }
- frameNum--;
- timestatus(frameNum,frameNum,s_freq[info.version][info.sampling_frequency]);
- fprintf(stderr,"\n");
- }
- fflush(stderr);
- exit(0);
- }
-
- /************************************************************************
- *
- * usage
- *
- * PURPOSE: Writes command line syntax to the file specified by #stderr#
- *
- ************************************************************************/
-
- void usage() /* print syntax & exit */
- {
- fprintf(stderr," LAMER Ain't an Mp3 Encoder (Reconstruction-iso)\n");
- fprintf(stderr," version %s\n",get_lame_version());
- fprintf(stderr," with GPSYCHO psycho-acoustic model (version %s). \n\n",get_psy_version());
- fprintf(stderr,"USAGE : %s [options] <infile> <outfile>\n",programName);
- fprintf(stderr,"OPTIONS :\n");
- fprintf(stderr," -m mode (s)tereo, (j)oint, (f)orce or (m)ono (default %c)\n",DFLT_MOD);
- fprintf(stderr," force = force ms_stereo on all frames. Faster and\n");
- fprintf(stderr," uses special Mid & Side masking thresholds\n");
- fprintf(stderr," -s sample freq frequency of input file (kHz) - default %4.1f\n",DFLT_SFQ);
- fprintf(stderr," -b <bitrate> set the bitrate, default 128kbps\n");
- fprintf(stderr," (for VBR, this sets the minimum bitrate)\n");
- fprintf(stderr," -x force byte-swapping of input\n");
- fprintf(stderr," -a downmix from stereo to mono file for mono encoding\n");
- fprintf(stderr," -e emp de-emphasis n/5/c (default %4c)\n",DFLT_EMP);
- fprintf(stderr," -c mark as copyright\n");
- fprintf(stderr," -o mark as non-original\n");
- fprintf(stderr," -f fast mode (low quality)\n");
- fprintf(stderr," -k disable sfb=21 cutoff\n");
- fprintf(stderr," -d allow channels to have different blocktypes\n");
- fprintf(stderr," -v use variable bitrate (VBR)\n");
- fprintf(stderr," -V n quality setting for VBR. default n=%i\n",VBR_q);
- fprintf(stderr," 0=high quality,bigger files. 9=smaller files\n");
- fprintf(stderr," -h use (maybe) some experimental quality improvements\n");
- #ifdef HAVEGTK
- fprintf(stderr," -g run graphical analysis on <infile>\n");
- #endif
- fprintf(stderr," -S don't print progress report\n");
- fprintf(stderr," -O use original (buggy) ISO psycho-acoustic model \n");
- fprintf(stderr,"\n<infile> and/or <outfile> can be \"-\", which means stdin/stdout.\n");
-
- exit(1);
- }
-
- /************************************************************************
- *
- * aiff_check
- *
- * PURPOSE: Checks AIFF header information to make sure it is valid.
- * Exits if not.
- *
- ************************************************************************/
-
- void aiff_check( char *file_name, IFF_AIFF *pcm_aiff_data, int *version)
- {
- if (pcm_aiff_data->sampleType != IFF_ID_SSND) {
- fprintf(stderr, "Sound data is not PCM in \"%s\".\n", file_name);
- exit(1);
- }
-
- if(SmpFrqIndex((long)pcm_aiff_data->sampleRate, version) < 0) {
- fprintf(stderr, "in \"%s\".\n", file_name);
- exit(1);
- }
-
- if (pcm_aiff_data->sampleSize != sizeof(short) * BITS_IN_A_BYTE) {
- fprintf(stderr, "Sound data is not %d bits in \"%s\".\n",
- sizeof(short) * BITS_IN_A_BYTE, file_name);
- exit(1);
- }
-
- if (pcm_aiff_data->numChannels != MONO &&
- pcm_aiff_data->numChannels != STEREO) {
- fprintf(stderr, "Sound data is not mono or stereo in \"%s\".\n",
- file_name);
- exit(1);
- }
-
- if (pcm_aiff_data->blkAlgn.blockSize != 0) {
- fprintf(stderr, "Block size is not %d bytes in \"%s\".\n",
- 0, file_name);
- exit(1);
- }
-
- if (pcm_aiff_data->blkAlgn.offset != 0) {
- fprintf(stderr, "Block offset is not %d bytes in \"%s\".\n",
- 0, file_name);
- exit(1);
- }
- }
-
-